<!--
  单行溢出提示组件（若文本未溢出，则不会出现提示信息）    zls-2022/05/31
      Attributes
          1、text           文字内容（必传）,默认为''
          2、width          文本内容的宽度，默认为'100%'
          3、height         文本内容的高度，默认为'100%'
          4、fontSize       文本内容大小，默认为14
          5、fontWeight     文本内容粗细，默认为400
          6、color          文本内容颜色，默认为'#fff'
          7、letterSpacing  文本内容的文字间隔，默认为0
          8、tipWidth       tip提示框的宽度，默认为'100%'
          9、placement      tip提示框出现的方向(left、top、right、bottom)，默认为 'bottom'
          10、offset        tip提示框的偏移量，默认为0

      Demo==>
          <ul class="tipList">
            <li v-for="(item, index) in list" :key="index">
              <span>{{ item.label }}</span>
              <z-tips :text="item.value"></z-tips>
            </li>
          </ul>

          list: [
            { label: '左侧文本：', value: '你的字写的也太多了吧，我真的是装不下了，在tips提示框中查看~' },
            { label: '左侧文本：', value: '该行文字较少' },
            { label: '左侧文本：', value: '该行文字及较多，这里实在放不下我了，我要藏起来~' }
          ]

          .tipList {
            > li {
              @include flex(center, center);
              height: 40px;
              padding-left: 15px;
            }
          }
-->
<template>
  <div class="z-tips" :style="[overflowPromptStyle]" ref="overflowPrompt" @click.stop="clickText">
    <u :style="[textStyle]">{{ text }}</u>
    <em :style="[textStyle]" ref="textRef">{{ text }}</em>
    <div :style="[tipStyle]" class="tipClass scrollbar" ref="tipClass">
      <span>{{ text }}</span>
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default { name: 'z-tips' }
</script>
<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { pxToRem } from '@/utils'

const props = defineProps({
  // 文字内容
  text: {
    type: [String, Number],
    default: ''
  },
  // 文本的宽度，默认为100%
  width: {
    type: [String, Number],
    default: '100%'
  },
  // 文本的高度，默认为100%
  height: {
    type: [String, Number],
    default: '100%'
  },
  // tip提示框的宽度，默认为100%
  tipWidth: {
    type: [String, Number],
    default: '100%'
  },
  // tip提示框出现的方向(left、top、right、bottom)，默认为 bottom
  placement: {
    type: String,
    default: 'bottom'
  },
  // tip提示框的偏移量，默认为10
  offset: {
    type: Number,
    default: 0
  },
  fontSize: {
    type: Number,
    default: 14
  },
  fontWeight: {
    type: [String, Number],
    default: 400
  },
  color: {
    type: String,
    default: '#666'
  },
  letterSpacing: {
    type: Number,
    default: 0
  }
})
const boxWidth = ref(0) // 容器的宽度
const boxHeight = ref(0) // 容器的高度
const textWidth = ref(0) // 原始文本的总长度
const showTip = ref(false) // 是否显示tip
const overflowPrompt = ref()
const textRef = ref()
const tipClass = ref()

// 整个盒子的样式
const overflowPromptStyle = computed(() => {
  const obj = {}
  obj.width = typeof props.width === 'string' ? props.width : pxToRem(props.width)
  obj.height = typeof props.height === 'string' ? props.height : pxToRem(props.height)
  return obj
})

// 文本内容的样式
const textStyle = computed(() => {
  const obj = {}
  obj.fontSize = pxToRem(props.fontSize)
  obj.fontWeight = props.fontWeight
  obj.color = props.color
  obj.letterSpacing = pxToRem(props.letterSpacing)
  return obj
})
// 提示框的样式
const tipStyle = computed(() => {
  const obj = {}
  obj.width = typeof props.tipWidth === 'string' ? props.tipWidth : pxToRem(props.tipWidth)
  if (props.placement === 'left') {
    obj.top = 0
    obj.right = pxToRem(boxWidth.value + props.offset)
  } else if (props.placement === 'top') {
    obj.bottom = pxToRem(boxHeight.value + props.offset)
  } else if (props.placement === 'right') {
    obj.top = 0
    obj.left = pxToRem(boxWidth.value + props.offset)
  } else {
    obj.top = pxToRem(boxHeight.value + props.offset)
  }
  if (textWidth.value > boxWidth.value && showTip.value) {
    obj.visibility = 'visible'
    obj.opacity = 1
    obj.transition = 'visibility 0.6s,opacity 0.6s'
  } else {
    obj.visibility = 'hidden'
    obj.opacity = 0
    obj.transition = 'visibility 0.6s,opacity 0.6s'
  }
  return obj
})
onMounted(() => {
  boxWidth.value = overflowPrompt.value.offsetWidth
  boxHeight.value = overflowPrompt.value.offsetHeight
  textWidth.value = textRef.value.offsetWidth
  document.addEventListener('touchend', touchendHandle)
})

onUnmounted(() => {
  document.removeEventListener('touchend', touchendHandle)
})

// 点击事件
function clickText(e) {
  if (e.target.tagName === 'U') {
    showTip.value = !showTip.value
  }
}

// 监听touchend事件
function touchendHandle(e) {
  if (tipClass.value && !tipClass.value.contains(e.target)) {
    showTip.value = false
  }
}
</script>

<style lang="scss" scoped>
.z-tips {
  flex: 1;
  position: relative;
  > u {
    width: 100%;
    line-height: 1.5;
    text-decoration: initial;
    @include oflowMore(1);
    position: relative;
    top: 50%;
    transform: translateY(-50%);
  }
  > em {
    position: absolute;
    z-index: -9999;
    left: -10000px;
    font-style: normal;
    white-space: nowrap;
  }
  > div {
    position: absolute;
    z-index: 999;
    background: #6c8ea0;
    color: #fff;
    font-weight: 100;
    border-radius: 5px;
    padding: 6px;
    letter-spacing: 1px;
    line-height: 18px;
    max-height: 400px;
    overflow-y: auto;
  }
}
</style>
